﻿<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>

  <xsl:output method="xml" indent="yes"/>

  <!-- Start deployment configuration creation -->
  <xsl:template match="/">

    <applications>

      <!-- Browse all applications -->
      <xsl:apply-templates select="//application" />

    </applications>
  </xsl:template>


  <!-- Start application Node -->
  <xsl:template match="application">

    <xsl:element name="application">
      <xsl:attribute name="name">
        <xsl:value-of select="@name"/>
      </xsl:attribute>

      <xsl:variable name="applicationName" select="@name" />

      <!-- Call deployment target -->
      <xsl:apply-templates select="//deploymentTarget[@applicationName=$applicationName]">
        <xsl:with-param name="application" select="." />
      </xsl:apply-templates>

    </xsl:element>

  </xsl:template>
  <!-- Start application Node -->

  <!-- Start read all configuration for a deployment target-->
  <xsl:template match="//deploymentTarget">
    <xsl:param name="application" />

    <!-- Search Deployment Node -->
    <xsl:apply-templates select="deploymentNode">
      <xsl:with-param name="application" select="$application" />
      <xsl:with-param name="environmentName" select="@environment" />
    </xsl:apply-templates>

  </xsl:template>

  <!-- Copy General configuration node whic contains logger configuration ans email configuration-->
  <xsl:template match="//configuration">
    <xsl:copy-of select="." />
  </xsl:template>

  <!-- Begin Apply template deploymentNode -->
  <xsl:template match ="//deploymentNode">
    <xsl:param name="application" />
    <xsl:param name="environmentName" />

    <xsl:variable name="serverName" select="@serverName" />

    <!-- Find Server configuration -->
    <xsl:variable name="server" select="//server[@name=$serverName]" />

    <!-- add components to be deployed -->
    <xsl:apply-templates select="component">
      <xsl:with-param name="server" select="$server" />
      <xsl:with-param name="application" select="$application" />
      <xsl:with-param name="environmentName" select="$environmentName" />
      <xsl:with-param name="deploymentNode" select="." />
    </xsl:apply-templates>


  </xsl:template>
  <!-- End Apply template deploymentNode -->


  <!-- Begin Apply component for Server-->
  <xsl:template match="//deploymentNode/component">
    <xsl:param name="application" />
    <xsl:param name="environmentName" />
    <xsl:param name="server" />
    <xsl:param name="deploymentNode" />
    <xsl:variable name="componentName" select="@name" />
    <xsl:variable name="middlewareTarget" select="./@middlewareTarget"/>
    <xsl:variable name="applicationPoolTarget" select="./@applicationPoolTarget"/>

    <!-- Find component definition-->
    <xsl:variable name="component" select="$application/components/component[@name=$componentName]"/>

    <!-- Find Middleware definition -->
    <xsl:variable name="middleware" select="//server[@name=$server/@name]/middlewares/middleware[@type=$component/@middlewareTarget]/executionContainer[@name=$middlewareTarget]" />

    <!-- Find application pool definition -->
    <xsl:variable name="applicationPool" select="//server[@name=$server/@name]/middlewares/middleware[@type=$component/@middlewareTarget]/applicationPools/applicationPool[@applicationPoolName=$applicationPoolTarget]" />


    <xsl:if test="$component/@componentType='WebApplicationIIS7'">

      <xsl:element name="recycle">
        <!-- add node Name -->
        <xsl:attribute name="name">
          <xsl:value-of select="$deploymentNode/@nodeName"/>
        </xsl:attribute>
        <!-- add serverName -->
        <xsl:attribute name="hostName">
          <xsl:value-of select="$server/@name"/>
        </xsl:attribute>

        <!-- add environment -->
        <xsl:attribute name="environment">
          <xsl:value-of select="$environmentName"/>
        </xsl:attribute>

        <!-- add environment -->
        <xsl:attribute name="component">
          <xsl:value-of select="@name"/>
        </xsl:attribute>

        <!-- add application Name -->
        <xsl:attribute name="application">
          <xsl:value-of select="$application/@name"/>
        </xsl:attribute>

      </xsl:element>

    </xsl:if>

  </xsl:template>
  <!-- End Apply component for Server-->

  <!-- Begin Apply template copy attributes from a node -->
  <xsl:template match="@*" mode="copyAttribute">
    <xsl:copy>
    </xsl:copy>
  </xsl:template>
  <!-- End Apply template component attributes to deployment node-->

  <!-- Begin Apply template component relative attributes to deployment node-->
  <xsl:template match="*" mode="ApplyRelativeAttributeValue">
    <xsl:param name="parent" />

    <!-- Attribute name come from the node name belong relativeAttributes-->
    <xsl:variable name="attributeName">
      <xsl:value-of select="name()"/>
    </xsl:variable>


    <!-- Concat targeted attribute value with relative value-->
    <xsl:attribute name="{$attributeName}">
      <xsl:apply-templates select="." mode="GetRelativeValue">
        <xsl:with-param name="parent" select="$parent" />
      </xsl:apply-templates>
    </xsl:attribute>

  </xsl:template>
  <!-- End Apply template component relative attributes to deployment node-->

  <xsl:template match="*" mode="GetRelativeValue">
    <xsl:param name="parent" />

    <!-- Read Targeted attribute Name to retrieve-->
    <xsl:variable name="targetedAttributeName">
      <xsl:value-of select="./@targetedAttributeName"/>
    </xsl:variable>

    <!-- Read Targeted attribute value on middleware-->
    <xsl:variable name="targetedAttributeValue">
      <xsl:value-of select="$parent/@*[name()=$targetedAttributeName]"/>
    </xsl:variable>

    <!-- Concat targeted attribute value with relative value-->
    <xsl:call-template name="EnsurePathEndTerminator">
      <xsl:with-param name="value" select="$targetedAttributeValue" />
      <xsl:with-param name="separator" select="./@separator" />
    </xsl:call-template>
    <xsl:if test="./@separator!=./@relativeValue">
      <xsl:value-of select="./@relativeValue"/>
    </xsl:if>

  </xsl:template>

  <!-- Function to Create a folder Path -->
  <xsl:template name="CreateServerFolderPathForApplication">
    <xsl:param name="folderPath" />
    <xsl:param name="application" />
    <xsl:param name="environment" />
    <xsl:param name="serverName" />


    <!-- String Folder Path\Application Name\Vversion-->
    <xsl:variable name="returnPath">
      <xsl:call-template name="EnsurePathEndTerminator">
        <xsl:with-param name="value" select="$folderPath" />
      </xsl:call-template>
      <xsl:value-of select="$environment" />\<xsl:value-of select="$application/@name"/>\V<xsl:value-of select="$application/@version"/>
    </xsl:variable>

    <!-- ensure last slash-->
    <xsl:call-template name="EnsurePathEndTerminator">
      <xsl:with-param name="value" select="$returnPath" />
    </xsl:call-template>
  </xsl:template>

  <!-- Function to ensure a separator at the end of a value -->
  <xsl:template name="EnsurePathEndTerminator">
    <xsl:param name="value" />
    <xsl:param name="separator" select="'\'" />

    <xsl:choose>
      <xsl:when test="$separator= substring($value, string-length($value) - string-length($separator) +1)">
        <xsl:value-of select="$value"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:variable name="returnValue">
          <xsl:value-of select="$value"/>
          <xsl:value-of select="$separator"/>
        </xsl:variable>
        <xsl:value-of select="$returnValue"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>
